package com.toune.dltools

import android.annotation.TargetApi
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.*
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.Nullable
import androidx.annotation.StringRes
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import com.qmuiteam.qmui.util.QMUIDisplayHelper
import java.lang.ref.WeakReference

/**
 * Snackbar工具类
 * 功能:
 * 1:设置Snackbar显示时间长短
 * 1.1:Snackbar.LENGTH_SHORT       [DLSnackbarUtils.Short]
 * 1.2:Snackbar.LENGTH_LONG        [DLSnackbarUtils.Long]
 * 1.3:Snackbar.LENGTH_INDEFINITE  [DLSnackbarUtils.Indefinite]
 * 1.4:CUSTOM                      [DLSnackbarUtils.Custom]
 * 2:设置Snackbar背景颜色
 * 2.1:color_info      [DLSnackbarUtils.info]
 * 2.2:color_confirm   [DLSnackbarUtils.confirm]
 * 2.3:color_warning   [DLSnackbarUtils.warning]
 * 2.4:color_danger    [DLSnackbarUtils.danger]
 * 2.5:CUSTOM          [DLSnackbarUtils.backColor]
 * 3:设置TextView(@+id/snackbar_text)的文字颜色
 * [DLSnackbarUtils.messageColor]
 * 4:设置Button(@+id/snackbar_action)的文字颜色
 * [DLSnackbarUtils.actionColor]
 * 5:设置Snackbar背景的透明度
 * [DLSnackbarUtils.alpha]
 * 6:设置Snackbar显示的位置
 * [DLSnackbarUtils.gravityFrameLayout]
 * [DLSnackbarUtils.gravityCoordinatorLayout]
 * 6.1:Gravity.TOP;
 * 6.2:Gravity.BOTTOM;
 * 6.3:Gravity.CENTER;
 * 7:设置Button(@+id/snackbar_action)文字内容 及 点击监听
 * [DLSnackbarUtils.setAction]
 * [DLSnackbarUtils.setAction]
 * 8:设置Snackbar展示完成 及 隐藏完成 的监听
 * [DLSnackbarUtils.setCallback]
 * 9:设置TextView(@+id/snackbar_text)左右两侧的图片
 * [DLSnackbarUtils.leftAndRightDrawable]
 * [DLSnackbarUtils.leftAndRightDrawable]
 * 10:设置TextView(@+id/snackbar_text)中文字的对齐方式
 * 默认效果就是居左对齐
 * [DLSnackbarUtils.messageCenter]   居中对齐
 * [DLSnackbarUtils.messageRight]    居右对齐
 * 注意:这两个方法要求SDK>=17.[View.setTextAlignment]
 * 本来想直接设置Gravity,经试验发现在 TextView(@+id/snackbar_text)上,design_layout_snackbar_include.xml
 * 已经设置了android:textAlignment="viewStart",单纯设置Gravity是无效的.
 * TEXT_ALIGNMENT_GRAVITY:[View.TEXT_ALIGNMENT_GRAVITY]
 * 11:向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
 * [DLSnackbarUtils.addView]
 * [DLSnackbarUtils.addView]
 * 注意:使用addView方法的时候要注意新加布局的大小和Snackbar内文字长度，Snackbar过大或过于花哨了可不好看
 * 12:设置Snackbar布局的外边距
 * [DLSnackbarUtils.margins]
 * [DLSnackbarUtils.margins]
 * 注意:经试验发现,调用margins后再调用 gravityFrameLayout,则margins无效.
 * 为保证margins有效,应该先调用 gravityFrameLayout,在 show() 之前调用 margins
 * SnackbarUtil.Long(bt9,"设置Margin值").backColor(0XFF330066).gravityFrameLayout(Gravity.TOP).margins(20,40,60,80).show();
 * 13:设置Snackbar布局的圆角半径值
 * [DLSnackbarUtils.radius]
 * 14:设置Snackbar布局的圆角半径值及边框颜色及边框宽度
 * [DLSnackbarUtils.radius]
 * 15:设置Snackbar显示在指定View的上方
 * [DLSnackbarUtils.above]
 * 注意:
 * 1:此方法实际上是 [DLSnackbarUtils.gravityFrameLayout]和[DLSnackbarUtils.margins]的结合.
 * 不可与 [DLSnackbarUtils.margins] 混用.
 * 2:暂时仅仅支持单行Snackbar,因为方法中涉及的[DLSnackbarUtils.calculateSnackBarHeight]暂时仅支持单行Snackbar高度计算.
 * 16:设置Snackbar显示在指定View的下方
 * [DLSnackbarUtils.bellow]
 * 注意:同15
 * 参考:
 * //写的很好的Snackbar源码分析
 * http://blog.csdn.net/wuyuxing24/article/details/51220415
 * //借鉴了作者部分写法,自定义显示时间 及 向Snackbar中添加View
 * http://www.jianshu.com/p/cd1e80e64311
 * //借鉴了作者部分写法,4种类型的背景色 及 方法调用的便捷性
 * http://www.jianshu.com/p/e3c82b98f151
 * //大神'工匠若水'的文章'Android应用坐标系统全面详解',用于计算Snackbar显示的精确位置
 * http://blog.csdn.net/yanbober/article/details/50419117
 * 示例:
 * 在Activity中:
 * int total = 0;
 * int[] locations = new int[2];
 * getWindow().findViewById(android.R.id.content).getLocationInWindow(locations);
 * total = locations[1];
 * SnackbarUtil.Custom(bt_multimethods,"10s+左右drawable+背景色+圆角带边框+指定View下方",1000*10)
 * .leftAndRightDrawable(R.mipmap.i10,R.mipmap.i11)
 * .backColor(0XFF668899)
 * .radius(16,1,Color.BLUE)
 * .bellow(bt_margins,total,16,16)
 * .show();
 * 作者:幻海流心
 * 邮箱:wall0920@163.com
 * 2016/11/2 13:56
 */
class DLSnackbarUtils {
    private constructor() {
        throw RuntimeException("禁止无参创建实例")
    }

    private constructor(@Nullable snackbarWeakRef: WeakReference<Snackbar>) {
        snackbarWeakReference = snackbarWeakRef
    }

    /**
     * 获取 mSnackbar
     * @return
     */
    val snackbar: Snackbar?
        get() = if (snackbarWeakReference?.get() != null) {
            DLSnackbarUtils.snackbarWeakReference!!.get()
        } else {
            null
        }

    /**
     * 设置mSnackbar背景色为  color_info
     */
    fun info(): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.view.setBackgroundColor(color_info)
        }
        return this
    }

    /**
     * 设置mSnackbar背景色为  color_confirm
     */
    fun confirm(): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.view.setBackgroundColor(color_confirm)
        }
        return this
    }

    /**
     * 设置Snackbar背景色为   color_warning
     */
    fun warning(): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.view.setBackgroundColor(color_warning)
        }
        return this
    }

    /**
     * 设置Snackbar背景色为   color_warning
     */
    fun danger(): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.view.setBackgroundColor(color_danger)
        }
        return this
    }

    /**
     * 设置Snackbar背景色
     * @param backgroundColor
     */
    fun backColor(@ColorInt backgroundColor: Int): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.view.setBackgroundColor(backgroundColor)
        }
        return this
    }

    /**
     * 设置TextView(@+id/snackbar_text)的文字颜色
     * @param messageColor
     */
    fun messageColor(@ColorInt messageColor: Int): DLSnackbarUtils {
        if (snackbar != null) {
            (snackbar!!.view.findViewById(R.id.snackbar_text) as TextView).setTextColor(
                messageColor
            )
        }
        return this
    }

    /**
     * 设置Button(@+id/snackbar_action)的文字颜色
     * @param actionTextColor
     */
    fun actionColor(@ColorInt actionTextColor: Int): DLSnackbarUtils {
        if (snackbar != null) {
            (snackbar!!.view
                .findViewById(R.id.snackbar_action) as Button).setTextColor(
                actionTextColor
            )
        }
        return this
    }

    /**
     * 设置   Snackbar背景色 + TextView(@+id/snackbar_text)的文字颜色 + Button(@+id/snackbar_action)的文字颜色
     * @param backgroundColor
     * @param messageColor
     * @param actionTextColor
     */
    fun colors(
        @ColorInt backgroundColor: Int,
        @ColorInt messageColor: Int,
        @ColorInt actionTextColor: Int
    ): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.view.setBackgroundColor(backgroundColor)
            (snackbar!!.view.findViewById(R.id.snackbar_text) as TextView).setTextColor(
                messageColor
            )
            (snackbar!!.view
                .findViewById(R.id.snackbar_action) as Button).setTextColor(
                actionTextColor
            )
        }
        return this
    }

    /**
     * 设置Snackbar 背景透明度
     * @param alpha
     * @return
     */
    fun alpha(alpha: Float): DLSnackbarUtils {
        var alpha = alpha
        if (snackbar != null) {
            alpha = if (alpha >= 1.0f) 1.0f else if (alpha <= 0.0f) 0.0f else alpha
            snackbar!!.view.alpha = alpha
        }
        return this
    }

    /**
     * 设置Snackbar显示的位置
     * @param gravity
     */
    fun gravityFrameLayout(gravity: Int): DLSnackbarUtils {
        if (snackbar != null) {
            val params: FrameLayout.LayoutParams = FrameLayout.LayoutParams(
                snackbar!!.view.layoutParams.width,
                snackbar!!.view.layoutParams.height
            )
            params.gravity = gravity
            snackbar!!.view.layoutParams = params
        }
        return this
    }

    /**
     * 设置Snackbar显示的位置,当Snackbar和CoordinatorLayout组合使用的时候
     * @param gravity
     */
    fun gravityCoordinatorLayout(gravity: Int): DLSnackbarUtils {
        if (snackbar != null) {
            val params: CoordinatorLayout.LayoutParams = CoordinatorLayout.LayoutParams(
                snackbar!!.view.layoutParams.width,
                snackbar!!.view.layoutParams.height
            )
            params.gravity = gravity
            snackbar!!.view.layoutParams = params
        }
        return this
    }

    /**
     * 设置按钮文字内容 及 点击监听
     * [Snackbar.setAction]
     * @param resId
     * @param listener
     * @return
     */
    fun setAction(
        @StringRes resId: Int,
        listener: View.OnClickListener?
    ): DLSnackbarUtils {
        return if (snackbar != null) {
            setAction(snackbar!!.view.resources.getText(resId), listener)
        } else {
            this
        }
    }

    /**
     * 设置按钮文字内容 及 点击监听
     * [Snackbar.setAction]
     * @param text
     * @param listener
     * @return
     */
    fun setAction(
        text: CharSequence?,
        listener: View.OnClickListener?
    ): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.setAction(text, listener)
        }
        return this
    }

    /**
     * 设置 mSnackbar 展示完成 及 隐藏完成 的监听
     * @param setCallback
     * @return
     */
    fun setCallback(setCallback: Snackbar.Callback?): DLSnackbarUtils {
        if (snackbar != null) {
            snackbar!!.setCallback(setCallback)
        }
        return this
    }

    /**
     * 设置TextView(@+id/snackbar_text)左右两侧的图片
     * @param leftDrawable
     * @param rightDrawable
     * @return
     */
    fun leftAndRightDrawable(
        @Nullable @DrawableRes leftDrawable: Int?,
        @Nullable @DrawableRes rightDrawable: Int?
    ): DLSnackbarUtils {
        return if (snackbar != null) {
            var drawableLeft: Drawable? = null
            var drawableRight: Drawable? = null
            if (leftDrawable != null) {
                try {
                    drawableLeft =
                        snackbar!!.view.resources.getDrawable(leftDrawable.toInt())
                } catch (e: Exception) {
                }
            }
            if (rightDrawable != null) {
                try {
                    drawableRight =
                        snackbar!!.view.resources.getDrawable(rightDrawable.toInt())
                } catch (e: Exception) {
                }
            }
            leftAndRightDrawable(drawableLeft, drawableRight)
        } else {
            this
        }
    }

    /**
     * 设置TextView(@+id/snackbar_text)左右两侧的图片
     * @param leftDrawable
     * @param rightDrawable
     * @return
     */
    fun leftAndRightDrawable(
        @Nullable leftDrawable: Drawable?,
        @Nullable rightDrawable: Drawable?
    ): DLSnackbarUtils {
        if (snackbar != null) {
            val message =
                snackbar!!.view.findViewById(R.id.snackbar_text) as TextView
            var paramsMessage =
                message.layoutParams as LinearLayout.LayoutParams
            paramsMessage =
                LinearLayout.LayoutParams(paramsMessage.width, paramsMessage.height, 0.0f)
            message.layoutParams = paramsMessage
            message.compoundDrawablePadding = message.paddingLeft
            val textSize = message.textSize.toInt()
            Log.e("Jet", "textSize:$textSize")
            leftDrawable?.setBounds(0, 0, textSize, textSize)
            rightDrawable?.setBounds(0, 0, textSize, textSize)
            message.setCompoundDrawables(leftDrawable, null, rightDrawable, null)
            val paramsSpace = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT,
                1.0f
            )
            (snackbar!!.view as Snackbar.SnackbarLayout).addView(
                Space(
                    snackbar!!.view.context
                ), 1, paramsSpace
            )
        }
        return this
    }

    /**
     * 设置TextView(@+id/snackbar_text)中文字的对齐方式 居中
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    fun messageCenter(): DLSnackbarUtils {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (snackbar != null) {
                val message =
                    snackbar!!.view.findViewById(R.id.snackbar_text) as TextView
                //View.setTextAlignment需要SDK>=17
                message.textAlignment = View.TEXT_ALIGNMENT_GRAVITY
                message.gravity = Gravity.CENTER
            }
        }
        return this
    }

    /**
     * 设置TextView(@+id/snackbar_text)中文字的对齐方式 居右
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    fun messageRight(): DLSnackbarUtils {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (snackbar != null) {
                val message =
                    snackbar!!.view.findViewById(R.id.snackbar_text) as TextView
                //View.setTextAlignment需要SDK>=17
                message.textAlignment = View.TEXT_ALIGNMENT_GRAVITY
                message.gravity = Gravity.CENTER_VERTICAL or Gravity.RIGHT
            }
        }
        return this
    }

    /**
     * 向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
     * @param layoutId  要添加的View的布局文件ID
     * @param index
     * @return
     */
    fun addView(layoutId: Int, index: Int): DLSnackbarUtils {
        return if (snackbar != null) {
            //加载布局文件新建View
            val addView =
                LayoutInflater.from(snackbar!!.view.context).inflate(layoutId, null)
            addView(addView, index)
        } else {
            this
        }
    }

    /**
     * 向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
     * @param addView
     * @param index
     * @return
     */
    fun addView(addView: View, index: Int): DLSnackbarUtils {
        if (snackbar != null) {
            val params = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            ) //设置新建布局参数
            //设置新建View在Snackbar内垂直居中显示
            params.gravity = Gravity.CENTER_VERTICAL
            addView.layoutParams = params
            (snackbar!!.view as Snackbar.SnackbarLayout).addView(addView, index)
        }
        return this
    }

    /**
     * 设置Snackbar布局的外边距
     * 注:经试验发现,调用margins后再调用 gravityFrameLayout,则margins无效.
     * 为保证margins有效,应该先调用 gravityFrameLayout,在 show() 之前调用 margins
     * @param margin
     * @return
     */
    fun margins(margin: Int): DLSnackbarUtils {
        return if (snackbar != null) {
            margins(margin, margin, margin, margin)
        } else {
            this
        }
    }

    /**
     * 设置Snackbar布局的外边距
     * 注:经试验发现,调用margins后再调用 gravityFrameLayout,则margins无效.
     * 为保证margins有效,应该先调用 gravityFrameLayout,在 show() 之前调用 margins
     * @param left
     * @param top
     * @param right
     * @param bottom
     * @return
     */
    fun margins(left: Int, top: Int, right: Int, bottom: Int): DLSnackbarUtils {
        if (snackbar != null) {
            val params: ViewGroup.LayoutParams = snackbar!!.view.layoutParams
            (params as MarginLayoutParams).setMargins(left, top, right, bottom)
            snackbar!!.view.layoutParams = params
        }
        return this
    }
    /**
     * 经试验发现:
     * 执行过[DLSnackbarUtils.backColor]后:background instanceof ColorDrawable
     * 未执行过[DLSnackbarUtils.backColor]:background instanceof GradientDrawable
     * @return
     */
    /*
    public SnackbarUtils radius(){
        Drawable background = snackbarWeakReference.get().getView().getBackground();
        if(background instanceof GradientDrawable){
            Log.e("Jet","radius():GradientDrawable");
        }
        if(background instanceof ColorDrawable){
            Log.e("Jet","radius():ColorDrawable");
        }
        if(background instanceof StateListDrawable){
            Log.e("Jet","radius():StateListDrawable");
        }
        Log.e("Jet","radius()background:"+background.getClass().getSimpleName());
        return new SnackbarUtils(mSnackbar);
    }
    */
    /**
     * 通过SnackBar现在的背景,获取其设置圆角值时候所需的GradientDrawable实例
     * @param backgroundOri
     * @return
     */
    private fun getRadiusDrawable(backgroundOri: Drawable): GradientDrawable? {
        var background: GradientDrawable? = null
        if (backgroundOri is GradientDrawable) {
            background = backgroundOri
        } else if (backgroundOri is ColorDrawable) {
            val backgroundColor = backgroundOri.color
            background = GradientDrawable()
            background.setColor(backgroundColor)
        } else {
        }
        return background
    }

    /**
     * 设置Snackbar布局的圆角半径值
     * @param radius    圆角半径
     * @return
     */
    fun radius(radius: Float): DLSnackbarUtils {
        var radius = radius
        if (snackbar != null) {
            //将要设置给mSnackbar的背景
            val background =
                getRadiusDrawable(snackbar!!.view.background)
            if (background != null) {
                radius = (if (radius <= 0) 12 else radius) as Float
                background.cornerRadius = radius
                snackbar!!.view.setBackgroundDrawable(background)
            }
        }
        return this
    }

    /**
     * 设置Snackbar布局的圆角半径值及边框颜色及边框宽度
     * @param radius
     * @param strokeWidth
     * @param strokeColor
     * @return
     */
    fun radius(radius: Int, strokeWidth: Int, @ColorInt strokeColor: Int): DLSnackbarUtils {
        var radius = radius
        var strokeWidth = strokeWidth
        if (snackbar != null) {
            //将要设置给mSnackbar的背景
            val background =
                getRadiusDrawable(snackbar!!.view.background)
            if (background != null) {
                radius = if (radius <= 0) 12 else radius
                strokeWidth =
                    if (strokeWidth <= 0) 1 else if (strokeWidth >= snackbar!!.view.findViewById<TextView>(R.id.snackbar_text).paddingTop
                    ) 2 else strokeWidth
                background.cornerRadius = radius.toFloat()
                background.setStroke(strokeWidth, strokeColor)
                snackbar!!.view.setBackgroundDrawable(background)
            }
        }
        return this
    }

    /**
     * 计算单行的Snackbar的高度值(单位 pix)
     * @return
     */
    private fun calculateSnackBarHeight(): Int {
        /*
        <TextView
                android:id="@+id/snackbar_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:paddingTop="@dimen/design_snackbar_padding_vertical"
                android:paddingBottom="@dimen/design_snackbar_padding_vertical"
                android:paddingLeft="@dimen/design_snackbar_padding_horizontal"
                android:paddingRight="@dimen/design_snackbar_padding_horizontal"
                android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"
                android:maxLines="@integer/design_snackbar_text_max_lines"
                android:layout_gravity="center_vertical|left|start"
                android:ellipsize="end"
                android:textAlignment="viewStart"/>
        */
        //文字高度+paddingTop+paddingBottom : 14sp + 14dp*2
        val SnackbarHeight: Int =
            QMUIDisplayHelper.dp2px(snackbar!!.view.context, 28) + QMUIDisplayHelper.sp2px(
                snackbar!!.view.context,
                14
            )
        Log.e(
            "Jet",
            "直接获取MessageView高度:" + snackbar!!.view.findViewById<TextView>(R.id.snackbar_text)
                .height
        )
        return SnackbarHeight
    }

    /**
     * 设置Snackbar显示在指定View的上方
     * 注:暂时仅支持单行的Snackbar,因为[DLSnackbarUtils.calculateSnackBarHeight]暂时仅支持单行Snackbar的高度计算
     * @param targetView        指定View
     * @param contentViewTop    Activity中的View布局区域 距离屏幕顶端的距离
     * @param marginLeft        左边距
     * @param marginRight       右边距
     * @return
     */
    fun above(
        targetView: View,
        contentViewTop: Int,
        marginLeft: Int,
        marginRight: Int
    ): DLSnackbarUtils {
        var marginLeft = marginLeft
        var marginRight = marginRight
        if (snackbar != null) {
            marginLeft = if (marginLeft <= 0) 0 else marginLeft
            marginRight = if (marginRight <= 0) 0 else marginRight
            val locations = IntArray(2)
            targetView.getLocationOnScreen(locations)
            Log.e("Jet", "距离屏幕左侧:" + locations[0] + "==距离屏幕顶部:" + locations[1])
            val snackbarHeight = calculateSnackBarHeight()
            Log.e("Jet", "Snackbar高度:$snackbarHeight")
            //必须保证指定View的顶部可见 且 单行Snackbar可以完整的展示
            if (locations[1] >= contentViewTop + snackbarHeight) {
                gravityFrameLayout(Gravity.BOTTOM)
                val params: ViewGroup.LayoutParams = snackbar!!.view.layoutParams
                (params as MarginLayoutParams).setMargins(
                    marginLeft,
                    0,
                    marginRight,
                    snackbar!!.view.resources
                        .displayMetrics.heightPixels - locations[1]
                )
                snackbar!!.view.layoutParams = params
            }
        }
        return this
    }

    //CoordinatorLayout
    fun aboveCoordinatorLayout(
        targetView: View,
        contentViewTop: Int,
        marginLeft: Int,
        marginRight: Int
    ): DLSnackbarUtils {
        var marginLeft = marginLeft
        var marginRight = marginRight
        if (snackbar != null) {
            marginLeft = if (marginLeft <= 0) 0 else marginLeft
            marginRight = if (marginRight <= 0) 0 else marginRight
            val locations = IntArray(2)
            targetView.getLocationOnScreen(locations)
            Log.e("Jet", "距离屏幕左侧:" + locations[0] + "==距离屏幕顶部:" + locations[1])
            val snackbarHeight = calculateSnackBarHeight()
            Log.e("Jet", "Snackbar高度:$snackbarHeight")
            //必须保证指定View的顶部可见 且 单行Snackbar可以完整的展示
            if (locations[1] >= contentViewTop + snackbarHeight) {
                gravityCoordinatorLayout(Gravity.BOTTOM)
                val params: ViewGroup.LayoutParams = snackbar!!.view.layoutParams
                (params as MarginLayoutParams).setMargins(
                    marginLeft,
                    0,
                    marginRight,
                    snackbar!!.view.resources
                        .displayMetrics.heightPixels - locations[1]
                )
                snackbar!!.view.layoutParams = params
            }
        }
        return this
    }

    /**
     * 设置Snackbar显示在指定View的下方
     * 注:暂时仅支持单行的Snackbar,因为[DLSnackbarUtils.calculateSnackBarHeight]暂时仅支持单行Snackbar的高度计算
     * @param targetView        指定View
     * @param contentViewTop    Activity中的View布局区域 距离屏幕顶端的距离
     * @param marginLeft        左边距
     * @param marginRight       右边距
     * @return
     */
    fun bellow(
        targetView: View,
        contentViewTop: Int,
        marginLeft: Int,
        marginRight: Int
    ): DLSnackbarUtils {
        var marginLeft = marginLeft
        var marginRight = marginRight
        if (snackbar != null) {
            marginLeft = if (marginLeft <= 0) 0 else marginLeft
            marginRight = if (marginRight <= 0) 0 else marginRight
            val locations = IntArray(2)
            targetView.getLocationOnScreen(locations)
            val snackbarHeight = calculateSnackBarHeight()
            val screenHeight: Int = QMUIDisplayHelper.getScreenHeight(snackbar!!.view.context)
            //必须保证指定View的底部可见 且 单行Snackbar可以完整的展示
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //为什么要'+2'? 因为在Android L(Build.VERSION_CODES.LOLLIPOP)以上,例如Button会有一定的'阴影(shadow)',阴影的大小由'高度(elevation)'决定.
                //为了在Android L以上的系统中展示的Snackbar不要覆盖targetView的阴影部分太大比例,所以人为减小2px的layout_marginBottom属性.
                if (locations[1] + targetView.height >= contentViewTop && locations[1] + targetView.height + snackbarHeight + 2 <= screenHeight) {
                    gravityFrameLayout(Gravity.BOTTOM)
                    val params: ViewGroup.LayoutParams = snackbar!!.view.layoutParams
                    (params as MarginLayoutParams).setMargins(
                        marginLeft,
                        0,
                        marginRight,
                        screenHeight - (locations[1] + targetView.height + snackbarHeight + 2)
                    )
                    snackbar!!.view.layoutParams = params
                }
            } else {
                if (locations[1] + targetView.height >= contentViewTop && locations[1] + targetView.height + snackbarHeight <= screenHeight) {
                    gravityFrameLayout(Gravity.BOTTOM)
                    val params: ViewGroup.LayoutParams = snackbar!!.view.layoutParams
                    (params as MarginLayoutParams).setMargins(
                        marginLeft,
                        0,
                        marginRight,
                        screenHeight - (locations[1] + targetView.height + snackbarHeight)
                    )
                    snackbar!!.view.layoutParams = params
                }
            }
        }
        return this
    }

    fun bellowCoordinatorLayout(
        targetView: View,
        contentViewTop: Int,
        marginLeft: Int,
        marginRight: Int
    ): DLSnackbarUtils {
        var marginLeft = marginLeft
        var marginRight = marginRight
        if (snackbar != null) {
            marginLeft = if (marginLeft <= 0) 0 else marginLeft
            marginRight = if (marginRight <= 0) 0 else marginRight
            val locations = IntArray(2)
            targetView.getLocationOnScreen(locations)
            val snackbarHeight = calculateSnackBarHeight()
            val screenHeight: Int = QMUIDisplayHelper.getScreenHeight(snackbar!!.view.context)
            //必须保证指定View的底部可见 且 单行Snackbar可以完整的展示
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //为什么要'+2'? 因为在Android L(Build.VERSION_CODES.LOLLIPOP)以上,例如Button会有一定的'阴影(shadow)',阴影的大小由'高度(elevation)'决定.
                //为了在Android L以上的系统中展示的Snackbar不要覆盖targetView的阴影部分太大比例,所以人为减小2px的layout_marginBottom属性.
                if (locations[1] + targetView.height >= contentViewTop && locations[1] + targetView.height + snackbarHeight + 2 <= screenHeight) {
                    gravityCoordinatorLayout(Gravity.BOTTOM)
                    val params: ViewGroup.LayoutParams = snackbar!!.view.layoutParams
                    (params as MarginLayoutParams).setMargins(
                        marginLeft,
                        0,
                        marginRight,
                        screenHeight - (locations[1] + targetView.height + snackbarHeight + 2)
                    )
                    snackbar!!.view.layoutParams = params
                }
            } else {
                if (locations[1] + targetView.height >= contentViewTop && locations[1] + targetView.height + snackbarHeight <= screenHeight) {
                    gravityCoordinatorLayout(Gravity.BOTTOM)
                    val params: ViewGroup.LayoutParams = snackbar!!.view.layoutParams
                    (params as MarginLayoutParams).setMargins(
                        marginLeft,
                        0,
                        marginRight,
                        screenHeight - (locations[1] + targetView.height + snackbarHeight)
                    )
                    snackbar!!.view.layoutParams = params
                }
            }
        }
        return this
    }

    /**
     * 显示 mSnackbar
     */
    fun show() {
        Log.e("Jet", "show()")
        if (snackbar != null) {
            Log.e("Jet", "show")
            snackbar!!.show()
        } else {
            Log.e("Jet", "已经被回收")
        }
    }

    companion object {
        //设置Snackbar背景颜色
        private const val color_info = -0xdf6b0d
        private const val color_confirm = -0xb34fb2
        private const val color_warning = -0x13ffb
        private const val color_danger = -0xbbcca

        //工具类当前持有的Snackbar实例
        private var snackbarWeakReference: WeakReference<Snackbar>? = null

        /**
         * 初始化Snackbar实例
         * 展示时间:Snackbar.LENGTH_SHORT
         * @param view
         * @param message
         * @return
         */
        fun Short(view: View?, message: String?): DLSnackbarUtils {
            /*
        <view xmlns:android="http://schemas.android.com/apk/res/android"
          class="android.support.design.widget.Snackbar$SnackbarLayout"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_gravity="bottom"
          android:theme="@style/ThemeOverlay.AppCompat.Dark"
          style="@style/Widget.Design.Snackbar" />
        <style name="Widget.Design.Snackbar" parent="android:Widget">
            <item name="android:minWidth">@dimen/design_snackbar_min_width</item>
            <item name="android:maxWidth">@dimen/design_snackbar_max_width</item>
            <item name="android:background">@drawable/design_snackbar_background</item>
            <item name="android:paddingLeft">@dimen/design_snackbar_padding_horizontal</item>
            <item name="android:paddingRight">@dimen/design_snackbar_padding_horizontal</item>
            <item name="elevation">@dimen/design_snackbar_elevation</item>
            <item name="maxActionInlineWidth">@dimen/design_snackbar_action_inline_max_width</item>
        </style>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <corners android:radius="@dimen/design_snackbar_background_corner_radius"/>
            <solid android:color="@color/design_snackbar_background_color"/>
        </shape>
        <color name="design_snackbar_background_color">#323232</color>
        */
            return DLSnackbarUtils(
                WeakReference<Snackbar>(
                    Snackbar.make(
                        view!!,
                        message!!,
                        Snackbar.LENGTH_SHORT
                    )
                )
            ).backColor(-0xcdcdce)
        }

        /**
         * 初始化Snackbar实例
         * 展示时间:Snackbar.LENGTH_LONG
         * @param view
         * @param message
         * @return
         */
        fun Long(view: View?, message: String?): DLSnackbarUtils {
            return DLSnackbarUtils(
                WeakReference<Snackbar>(
                    Snackbar.make(
                        view!!,
                        message!!,
                        Snackbar.LENGTH_LONG
                    )
                )
            ).backColor(-0xcdcdce)
        }

        /**
         * 初始化Snackbar实例
         * 展示时间:Snackbar.LENGTH_INDEFINITE
         * @param view
         * @param message
         * @return
         */
        fun Indefinite(view: View?, message: String?): DLSnackbarUtils {
            return DLSnackbarUtils(
                WeakReference<Snackbar>(
                    Snackbar.make(
                        view!!,
                        message!!,
                        Snackbar.LENGTH_INDEFINITE
                    )
                )
            ).backColor(-0xcdcdce)
        }

        /**
         * 初始化Snackbar实例
         * 展示时间:duration 毫秒
         * @param view
         * @param message
         * @param duration 展示时长(毫秒)
         * @return
         */
        fun Custom(
            view: View?,
            message: String?,
            duration: Int
        ): DLSnackbarUtils {
            return DLSnackbarUtils(
                WeakReference<Snackbar>(
                    Snackbar.make(
                        view!!,
                        message!!,
                        Snackbar.LENGTH_SHORT
                    ).setDuration(duration)
                )
            ).backColor(-0xcdcdce)
        }
    }
}